const zbTool = function () {
    this.isArray = function (o){
        return Object.prototype.toString.call(o) === '[object Array]';
    }

    //查找元素在二维数组中的索引值
    this.arraySearch = function (arr, key, val) {
        for (let i=0; i<arr.length; i++) {
            if (arr[i][key] !== 'undefined' && arr[i][key] === val) {
                return arr[i];
            }
        }
        return false;
    }

    //获取随机数
    this.getRandom = function (len) {
        let char = '';
        for (let i=0; i<len; i++) {
            char += Math.floor(Math.random()*10);
        }

        return char;
    }

    this.getYear = function () {
        let myDate = new Date();
        return myDate.getFullYear();
    }

    this.getMonth = function () {
        let myDate = new Date();
        return myDate.getMonth() + 1;
    }

    this.getDay = function () {
        let myDate = new Date();
        return myDate.getDate();
    }

    this.getToday = function (gap='-') {
        let d = new Date();
        d.setTime(d.getTime());
        let year = d.getFullYear();
        let month = d.getMonth()+1;
        let day = d.getDate();
        month = strPad(month.toString(),'0', 2 );
        day = strPad(day.toString(), '0', 2);
        return year + gap + month + gap + day;
    }

    //给字符串str补上前导字符pad, 最终使str总长为length
    this.strPad = function (str, pad, length) {
        var padn = length - str.length;
        var pads = '';

        for (i =0; i < padn ; i++) {
            pads += pad;
        }

        return pads + str;
    }

    //将字符串拆分成键值对
    this.explodeArgs = function (str, char1, char2) {
        let arr = str.split(char1);
        let list = {};
        for (let i = 0; i < arr.length; i++) {
            let tmp = arr[i].split(char2);
            list[tmp[0]] = tmp[1];
        }

        return list;
    }

    this.buildUrl = function(prefix, obj) {
        let param = this.parseQuery(prefix);

        for (let i in obj) {
            param[i] = obj[i]; //去掉重复的键, 用obj中的覆盖prefix中的
        }

        let arr = [];
        for (let j in param) {
            arr.push(j + '=' + param[j]);
        }

        let str = arr.join('&');

        let url = '';
        if (prefix.indexOf('?') !== -1) {
            let u =prefix.split('?');
            url = u[0] + '?' + str;
        } else {
            url = prefix + '?' + str;
        }

        return url;
    }

    this.parseQuery = function(query) {
        let pos = query.indexOf('?');
        if (pos === -1) {
            return {};
        }

        query = query.substring(pos + 1);
        query = decodeURIComponent(query);

        if (query.length === 0) {
            return {};
        }

        let items = null, item = null, name = null, value = null;

        if (query.indexOf('&') === -1) {
            items = query.split("=");
            name = items[0];
            value = items[1]
            let tmp = {};
            tmp[name] = value;
            return tmp;
        }

        let args = {};
        items = query.split("&");
        for(let i=0; i < items.length; i++){
            item = items[i].split("=");
            if(item[0]){
                name = item[0];
                value = item[1] ? item[1] : "";
                args[name] = value;
            }
        }

        return args;
    }

    this.go_home = function() {
        window.location.href = '/';
    }

    this.activeBorderBottom = function(id, color='#7E57C2') {
        if (document.getElementById(id) !== null) {
            let brothers = document.getElementById(id).parentNode.children;
            for (let i=0; i<brothers.length; i++) {
                brothers[i].style.borderBottom = '';
            }

            document.getElementById(id).style.borderBottom = '2px solid '+color;
        }
    }

    //获取嵌套数组/对象中的值
    // let obj = {'aa': {'xx':'cc', '0': 0, '1': '1', '-1': -1}}; getObjChild(obj, 'aa.xx')
    this.getObjChild = function (obj, key, gap='.') {
        let tmp = {};
        let arr = key.split(gap); //将key拆成数组

        if (obj[arr[0]]) {
            tmp = obj[arr[0]];
            for (let i=1; i<arr.length; i++) { //逐层进入匹配查找
                let is_found = false;
                if (typeof tmp === 'object') {
                    for(let j in tmp) {
                        if (j === arr[i]) {
                            tmp = tmp[j];
                            is_found = true;
                            break;
                        }
                    }
                }

                if (!is_found) {
                    tmp = false;
                    console.log('未找到 '+ arr[i]);
                    break;
                }
            }
        } else {
            console.log('未找到 '+ arr[0]);
            tmp = false;
        }

        return tmp;
    }

    this.redirect = function (url, isNew=false){
        if (isNew) {
            window.open(url);
        } else {
            window.location.href = url;
        }
    }

    this.refresh = function (isForce = true) {
        window.location.reload(isForce);
    }

    this.reload = function (isForce = true) {
        window.location.reload(isForce);
    }

    this.stringToEntity = function(str,radix){
        let arr=str.split('')
        radix=radix||0
        let tmp=arr.map(item=>
            `&#${(radix?'x'+item.charCodeAt(0).toString(16):item.charCodeAt(0))};`).join('')
        console.log(`'${str}' 转实体为 '${tmp}'`)
        return tmp
    }

    this.entityToString = function(entity){
        let entities=entity.split(';')
        entities.pop()
        let tmp=entities.map(item=>String.fromCharCode(
            item[2]==='x'?parseInt(item.slice(3),16):parseInt(item.slice(2)))).join('')
        console.log(`'${entity}' 转字符串为 '${tmp}'`)
        return tmp
    }

    this.encodeObj = function (obj) {
        return encodeURIComponent(JSON.stringify(obj));
    }

    this.decodeObj = function (str) {
        return JSON.parse(decodeURIComponent(str));
    }

    this.htmlToNode = function(html) {
        let div = document.createElement('div');
        div.innerHTML = html;
        return div.firstElementChild;
    }

    /**
     * @param node HTML DOM节点, 注意不是string
     * @param arr json数组 注意是数组类型
     * @return string 返回HTML字符串, 注意不是DOM节点
     */
    this.repeatNode = function (node, arr) {
        let out = [];
        for (let i=0; i<arr.length; i++) {
            let tmp = node.outerHTML;
            tmp = tmp.replace(/\s/g, ' '); //去掉回车换行, 减少空白符

            let map = arr[i];

            //先渲染内层的数组
            for (let j in map) {
                if (map[j] instanceof Array) { //数组, 递归替换
                    let subNode = node.querySelector('.'+j);
                    if (subNode) {
                        let subHtml = this.repeatNode(subNode, map[j]); //递归
                        let subTpl = subNode.outerHTML.replace(/\s/g, ' ');
                        tmp = tmp.replace(subTpl, subHtml);
                    }
                }
            }

            //再渲染内层的对象
            for (let j in map) {
                if (map[j] instanceof Object && !(map[j] instanceof Array)) { //对象, 递归替换
                    let subNode = node.querySelector('.'+j);
                    if (subNode) {
                        let subHtml = this.repeatNode(subNode, [map[j]]); //递归
                        let subTpl = subNode.outerHTML.replace(/\s/g, ' ')
                        tmp = tmp.replace(subTpl, subHtml);
                    }
                }
            }

            //最后渲染外层的键值对/字符串
            for (let j in map) {
                if (typeof map[j] === 'string' || typeof map[j] === 'number') { //字符串, 直接替换
                    let re = new RegExp('{' + j + '}', 'g');
                    tmp = tmp.replace(re, map[j]);
                }
            }

            out.push(tmp);
        }

        return out.join('');
    }

    //替换字符串
    this.repeatString = function (tplDom, arr, func=null) {
        if (tplDom.length === 0) {
            console.log('字符串长度为空');
            return;
        }

        if (arr.length === 0) {
            console.log('数据为空');
            return tplDom;
        }

        let tpl = tplDom;
        let out = '';
        for (let i=0; i<arr.length; i++) {
            if (typeof func === 'function') {
                arr[i] = func(arr[i]);
            }
            let map = arr[i];
            let tmp = tpl;
            for (let j in map) {
                let re = new RegExp('{' + j + '}', 'g');
                tmp = tmp.replace(re, map[j]);
            }

            let re = new RegExp('{_idx}', 'g');
            tmp = tmp.replace(re, parseInt(i)+1);

            out += tmp;
        }

        return out;
    };

    //替换dom内层html内容
    this.repeatInnerHTML = function (selector, arr, func=null) {
        let tplDom = document.querySelector(selector);
        if (!tplDom) {
            console.log('未找到: '+selector);
            return;
        }

        tplDom.innerHTML = this.repeatString(tplDom.innerHTML, arr, func);
    }

    //替换dom
    this.repeatOuterHTML = function (selector, arr, func=null) {
        let tplDom = document.querySelector(selector);
        if (!tplDom) {
            console.log('未找到: '+selector);
            return;
        }

        tplDom.outerHTML = this.repeatString(tplDom.outerHTML, arr, func);
    };

    this.getHtmlById = function (id){
        return document.getElementById(id).innerHTML;
    };

    this.setHtmlById = function (id, str=''){
        document.getElementById(id).innerHTML = str;
    };

    //替换dom节点，id: 被替换的dom的id，str: 替换后的内容
    this.replaceDom = function (id, str){
        let dom = document.getElementById(id);
        if (dom) {
            dom.outerHTML = str;
        }
    }

    //用回调函数处理数组的每一个元素
    this.formatArray = function (arr, func) {
        for (let i=0; i<arr.length; i++) {
            arr[i] = func(arr[i]);
        }

        return arr;
    }

    this.getInputs = function (id, tagName) {
        let data = {};
        let arrTagName = tagName.split(',');
        for (let j=0; j<arrTagName.length; j++) {
            let tname = arrTagName[j];
            let inputs = document.getElementById(id).getElementsByTagName(tname);
            for (let i=0; i<inputs.length; i++) {
                let k = inputs[i].name;
                let v = inputs[i].value;

                let type = inputs[i].type;
                if (type === 'checkbox') {
                    if (inputs[i].checked === true) {
                        v = 1;
                    } else {
                        v = 0;
                    }
                }

                data[k] = v;
            }
        }

        console.log(data);
        return data;
    }

    this.goScrollTop = function () {
        //把内容滚动指定的像素数（第一个参数是向右滚动的像素数，第二个参数是向下滚动的像素数）
        //向上是负数，向下是正数
        window.scrollBy(0, -100);
        //延时递归调用，模拟滚动向上效果
        scrolldelay = setTimeout('goScrollTop()', 30);
        //获取scrollTop值，声明了DTD的标准网页取document.documentElement.scrollTop，
        //否则取document.body.scrollTop；因为二者只有一个会生效，另一个就恒为0，所以取和值可以得到网页的真正的scrollTop值
        let sTop = document.documentElement.scrollTop + document.body.scrollTop;
        //判断当页面到达顶部，取消延时代码（否则页面滚动到顶部会无法再向下正常浏览页面）
        if (sTop <= 0) {
            clearTimeout(scrolldelay);
        }
    }

    //获取地理位置, 但使用的是 googleapi
    this.getPosition = function () {
        if ('geolocation' in navigator) {
            navigator.geolocation.getCurrentPosition(function(pos){
                console.log(pos)
            }, function(err){
                console.log(err)
            })

        }
    }

    //获取枚举值的名字
    this.getListNameByValue = function (obj, val) {
        let name = val;
        for (let key in obj) {
            if (key === val) {
                name = obj[key];
                break;
            }
        }

        return name;
    }
}